package com.fvision.camera.manager;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;

import com.fvision.camera.iface.ICameraStateChange;
import com.fvision.camera.iface.IProgressBack;
import com.fvision.camera.util.Cmd_Const;
import com.fvision.camera.util.LogUtils;
import com.huiying.cameramjpeg.UvcCamera;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * Created by zoulequan on 2019/3/23.
 */

public class DevUpgradeManager implements ICameraStateChange {
    private static DevUpgradeManager _instance;
    public static final int WHAT_SEND_FILE_TO_DEV_IMP = 55;
    public static final int WHAT_LOCK_TIME_OUT = 56;
    private boolean sendLock = false;
    private IProgressBack mIProgressBack;
    private String fileName;

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case WHAT_SEND_FILE_TO_DEV_IMP:
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            sendFileToDevImp();
                        }
                    }).start();
                    break;
                case WHAT_LOCK_TIME_OUT:
                    sendLock = false;
                    break;
            }
        }
    };

    public static DevUpgradeManager getInstance() {
        if (_instance == null) {
            _instance = new DevUpgradeManager();
        }
        return _instance;
    }

    public int checkUpgradeFile() {
        return CmdManager.getInstance().checkUpgradeFile();
    }

    public int startUpgrade() {
        int ret = CmdManager.getInstance().startUpgrade();
        if (ret == Cmd_Const.DEV_UPGRADE_START) {
            UvcCamera.getInstance().stopPreview();
            UvcCamera.getInstance().releaseUvccamera();
        }
        return ret;
    }

    /**
     * 下载
     *
     * @param upgradeFile
     * @param back
     */
//    public void sendFileToDevThread(final String upgradeFile,final IProgressBack back){
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                sendFileToDev(upgradeFile,back);
//            }
//        }).start();
//    }
    public void sendFileToDevThread(String upgradeFile, IProgressBack back) {
        if (!CmdManager.getInstance().isSupperDevUpgrade()) {
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_VERSION_NOT_SUPPER, "记录仪版本不支持，版本必须大于等于 1.2.3 小于 2.0.0，或 大于等于 2.2.3");
            }
            return;
        }

        if (!CmdManager.getInstance().getCurrentState().isCam_sd_state()) {
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_NOT_DETECTED_TF, "未检测到TF卡");
            }
            return;
        }

        if (sendLock) {
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_SENDING, "正在发送固件到记录仪,请稍后再试...");
            }
            return;
        }
        sendLock = true;
        mHandler.removeMessages(WHAT_LOCK_TIME_OUT);
        mHandler.sendEmptyMessageDelayed(WHAT_LOCK_TIME_OUT, 300000);
        mIProgressBack = back;
        fileName = upgradeFile;
        if (CmdManager.getInstance().getCurrentState().isCam_rec_state()) {
            CmdManager.getInstance().recToggle();
            CameraStateIml.getInstance().addListener(this);
            LogUtils.d("正在关闭录像");
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                sendFileToDevImp();
            }
        }).start();
    }

    private void sendFileToDevImp() {
        LogUtils.d("devUpgrade 开始发送固件到记录仪");
        CmdManager.getInstance().openWriteFile();
        byte[] fileData = readFile(fileName, mIProgressBack);
        if (fileData == null) {
            sendLock = false;
            return;
        }

        int singleSendSize = 8 * 1024;//单次写入的字节数
        int totalDataSize = 0;//总共需要发送的包数
        byte[] endData = null;//最后一包
        if (fileData.length % singleSendSize > 0) {
            endData = new byte[fileData.length % singleSendSize];
            totalDataSize = fileData.length / singleSendSize + 1;
            System.arraycopy(fileData, (totalDataSize - 1) * singleSendSize, endData, 0, endData.length);//最后一包的数据
        }

        for (int i = 0; i < fileData.length / singleSendSize; i++) {
            if (mIProgressBack != null) {
                float progress = i * 100 / (fileData.length / singleSendSize);
                LogUtils.d("total = " + fileData.length / singleSendSize + " i = " + i + " progress " + progress + "%");
                mIProgressBack.onProgress(progress);
            }
            byte[] singleData = new byte[singleSendSize];
            System.arraycopy(fileData, i * singleSendSize, singleData, 0, singleData.length);
            int ret = CmdManager.getInstance().writeFileData(singleData, i);

            if (ret == 0xaa) {
                if (mIProgressBack != null) {
                    mIProgressBack.onFail(Cmd_Const.DEV_UPGRADE_FILE_WRITE_ERROR, "写数据错误!0x66 打开失败 0x77 写入失败 0x55 未检测到TF卡 错误码:" + ret);
                }
                sendLock = false;
                return;
            }
        }

        if (endData != null && totalDataSize > 0) {
            int ret = CmdManager.getInstance().writeFileData(endData, totalDataSize);
            if (ret == 0xaa) {
                if (mIProgressBack != null) {
                    mIProgressBack.onFail(Cmd_Const.DEV_UPGRADE_FILE_WRITE_ERROR, "写数据错误!0x66 打开失败 0x77 写入失败 0x55 未检测到TF卡 错误码:" + ret);
                }
                sendLock = false;
                return;
            }
        }
        CmdManager.getInstance().closeReadFile();
        if (mIProgressBack != null) {
            mIProgressBack.onSuccess("Success");
        }
        sendLock = false;
    }

    public byte[] readFile(String filePath, IProgressBack back) {
        if (TextUtils.isEmpty(filePath)) {
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_FILEPATH_IS_EMPTY, "参数1:为空");
            }
            sendLock = false;
            return null;
        }
        File file = new File(filePath);
        if (!file.exists()) {
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_FILE_NOT_EXISTS, "指定路径的固件文件不存在");
            }
            sendLock = false;
            return null;
        }
        FileInputStream fis = null;
        byte[] buffer = null;
        try {
            fis = new FileInputStream(file);
            int length = fis.available();

            buffer = new byte[length];
            fis.read(buffer);

            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_IO_EXCEPTION, "找不到文件 FileNotFoundException");
            }
            sendLock = false;
        } catch (IOException e) {
            e.printStackTrace();
            if (back != null) {
                back.onFail(Cmd_Const.DEV_UPGRADE_IO_EXCEPTION, "IO异常 " + e.getMessage());
            }
            sendLock = false;
        }
        return buffer;
    }

    @Override
    public void stateChange() {
        if (!CmdManager.getInstance().getCurrentState().isCam_rec_state()) {
            LogUtils.d("关闭录像成功，开始发送固件");
            mHandler.sendEmptyMessage(WHAT_SEND_FILE_TO_DEV_IMP);
            CameraStateIml.getInstance().delListener(this);
        }
    }
}
